
# 函数
# 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()
# return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的return相当于返回 None
from math import pi
def circularArea(radius):
	return pi*radius*radius

#r = float(input("Please input circular radius:"))
r = 3.14
print("circular area:%.2f" % (circularArea(r)))
print()

'''
可变(mutable)与不可变(immutable)对象
	在 python 中,strings, tuples 和 numbers 是不可更改的对象,而 list, dict 等则是可以修改的对象.
		不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a.
		可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了.
	python 函数的参数传递:
		不可变类型:类似 c++ 的值传递,如 整数、字符串、元组.如fun（a）,传递的只是a的值,没有影响a对象本身.比如在 fun（a）内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身.
		可变类型:类似 c++ 的引用传递,如 列表,字典.如 fun（la）,则是将 la 真正的传过去,修改后fun外部的la也会受影响.
	python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象.
'''
def immutableInt(im):
	im = 100
	print("Function:", im)

print("===Immutable===")
a = 0
print("Befor:", a)
immutableInt(a)
print("After:", a)
print()

def mutableList(m):
	m.extend(['m', 'u', 't', 'a', 'b', 'l', 'e'])
	print("Function:", m)

print("===Mutable===")
a = ['l', 'i', 's', 't']
print("Befor:", a)
mutableList(a)
print("After:", a)
print()

'''
以下是调用函数时可使用的正式参数类型:
	位置参数:与声明相同数量和顺序的参数
	关键字参数:使用关键字参数来确定传入的参数值
	默认参数:未传递参数则使用默认参数值
	不定长参数:所有未命名的参数存放在加星号*的变量中
'''
def printStrInt(str, num=1234, *varTuple):
	print(str, num, varTuple)
	return

printStrInt("One", 1001)
printStrInt(num=1002, str="Two")
printStrInt("Three", 1003, 123456, 'varTuple')
print()

# 匿名函数 lambda
# lambda [arg1[, arg2, ... argn]]:expression
power = lambda x, y : x**y
print(power(2, 1024))
print()

'''
变量作用域
	L （Local）		局部作用域
	E （Enclosing）	闭包函数外的函数中
	G （Global）	全局作用域
	B （Built-in）	内建作用域
以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找（例如闭包）,再找不到就会去全局找,再者去内建中找.
只有模块（module）,类（class）以及函数（def、lambda）才会引入新的作用域.
'''

'''
global用于内部作用域修改外部作用域的变量
nonlocal用于修改嵌套作用域（enclosing 作用域、外层非全局作用域）中的变量
'''
g1 = "1-G"
g2 = "2-G"
def funT():
	g1 = "1-I"
	global g2
	g2 = "2-I"
	print("I-I:", g1, g2)

print("G-B:", g1, g2)
funT()
print("G-A:", g1, g2)
print()

n1 = "1-G"
n2 = "2-G"
n3 = "3-G"
print("G-B:", n1, n2, n3)
def outer():
	n1 = "1-O"
	n2 = "2-O"
	n3 = "3-O"
	print("O-B:", n1, n2, n3)
	def inner():
		n1 = "1-I"
		global n2
		n2 = "2-I"
		nonlocal n3
		n3 = "3-I"
		print("I-I:", n1, n2, n3)
	inner()
	print("O-A:", n1, n2, n3)
outer()
print("G-A:", n1, n2, n3)


